//
//  YYStateMachine.m
//  LearnObjectiveC
//
//  Created by client on 2017/9/18.
//  Copyright © 2017年 吴可高. All rights reserved.
//

#import "YYStateMachine.h"
#import "YYStateHeader.h"

void * YYStateMachineDefinitionKey = & YYStateMachineDefinitionKey;

@interface YYStateMachine ()
@property(nonatomic,strong) NSMutableSet * mutableStates;
@property(nonatomic,strong) NSMutableSet * mutableEvents;
@end
@implementation YYStateMachine

- (instancetype)init
{
    self = [super init];
    if (self) {
        _mutableEvents = [[NSMutableSet alloc]init];
        _mutableStates = [[NSMutableSet alloc]init];
    }
    return self;
}

-(void)addState:(NSString *)state
{
    [self.mutableStates addObject:state];
    if (!self.initialState) {
        self.initialState = state;
    }
}

-(void)when:(NSString *)eventName transitionForm:(NSString *)from to:(NSString *)to
{
    YYEvent * event = [self eventWithName:eventName];
    YYTransition * transition = [YYTransition transitionFrom:from to:to];
    if (!event) {
        event = [YYEvent eventWithName:eventName transitions:[NSSet setWithObject:transition]];
    }
    else
    {
        [self.mutableEvents removeObject:event];
        event = [event addTransition:transition];
    }
    [self.mutableEvents addObject:event];
}

-(NSString *)nextStateFrom:(NSString *)from forEvent:(NSString *)eventName
{
    YYEvent * event = [self eventWithName:eventName];
    for (YYTransition * transition in event.transitions) {
        if ([transition.from isEqualToString:from]) {
            return transition.to;
        }
    }
    return nil;
}

-(void)before:(NSString *)eventName do:(YYStateMachineTransitionCallback)callback
{
    YYEvent * oldEvent =[self eventWithName:eventName];
    [self.mutableEvents removeObject:oldEvent];
    YYEvent * newEvent = [oldEvent addBeforeCallback:callback];
    [self.mutableEvents addObject:newEvent];
}

-(void)after:(NSString *)eventName do:(YYStateMachineTransitionCallback)callback
{
    YYEvent * oldEvent =[self eventWithName:eventName];
    [self.mutableEvents removeObject:oldEvent];
    YYEvent * newEvent = [oldEvent addAfterCallback:callback];
    [self.mutableEvents addObject:newEvent];
}

-(NSSet *)states
{
    return [NSSet setWithSet:self.mutableStates];
}

-(NSSet *)events
{
    return [NSSet setWithSet:self.mutableEvents];
}

-(void)setInitialState:(NSString *)defaultState
{
    [self willChangeValueForKey:@"initialState"];
    _initialState = defaultState;
    [self.mutableStates addObject:defaultState];
    [self didChangeValueForKey:@"initialState"];
}


-(YYEvent *)eventWithName:(NSString *)name
{
    for (YYEvent * event in self.events) {
        if ([event.name isEqualToString:name]) {
            return event;
        }
    }
    return nil;
}
@end
